﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.ComponentModel;
using Proggy.Web.Cms.Core.Configuration;
using Proggy.Web.Cms.Core.ViewModels;
using Proggy.Web.Cms.PropertyTypes;

namespace Proggy.Web.Cms.Core.ModelBinding
{
    /// <summary>
    /// http://stackoverflow.com/questions/6412615/unvalidated-ivalueprovider-getvalue ???
    /// </summary>
    public class ConfigureDragAndDropPartViewModelBinder : DefaultModelBinder
    {
        

        protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
        {
            // check descriptor
            if (propertyDescriptor.Name == "PropertyType")
            {
                // get elname
                var elName = controllerContext.RequestContext.HttpContext.Request["part"];

                // get el
                var el = DragAndDropManager.DragAndDropPartsCache.Single(x => x.Name == elName);

                // get type
                var type = el.PropertyType;

                // create instance
                var instance = Activator.CreateInstance(el.PropertyType);

                // get props of instanc
                var instanceProps = type.GetProperties();

                // get form
                var formKeys = controllerContext.RequestContext.HttpContext.Request.Form.AllKeys;
                var form = controllerContext.RequestContext.HttpContext.Request.Form;

                // iterate props
                foreach (var propt in instanceProps)
                {
                    if (formKeys.Contains("PropertyType." + propt.Name))
                    {
                        // get form val
                        var formVal = form["PropertyType." + propt.Name];

                        // check true,false
                        if (formVal == "true,false") {
                            formVal = "true";
                        }

                        // start safe value
                        object safeValue = new object();
                        
                        try
                        {

                            // convert
                            Type t =
                                Nullable.GetUnderlyingType(propt.PropertyType) ?? propt.PropertyType;
                            safeValue = (string.IsNullOrEmpty(formVal)) ? null
                                                               : Convert.ChangeType(formVal, t);
                        }
                        catch {
                            safeValue = true;
                        }

                        // create instance
                        propt.SetValue(instance, safeValue, null);
                    }
                }

                return instance;
            }

            //
            return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);

        }
    }
}
